package com.sheepone.util;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.ClassUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.Map;

/**
 * @author Miss.杨
 * @description
 * @since 2024/2/20 - 22:44
 */
public class ObjectUtil {
    private ObjectUtil() {
    }

    public static <T> T getOrDefault(T value, T defaultValue) {
        return value == null ? defaultValue : value;
    }


    /**
     * 判断是否是基本类型
     *
     * @param clazz
     * @return
     */
    public static boolean isBasicType(Class<?> clazz) {
        if (clazz.isPrimitive()) {
            return true;
        }
        if (clazz == String.class || clazz == Character.class || clazz == Boolean.class) {
            return true;
        }
        if (clazz == Byte.class || clazz == Short.class || clazz == Integer.class || clazz == Long.class) {
            return true;
        }
        return clazz == Float.class || clazz == Double.class;
    }


    public static boolean isBasicComponentType(Class<?> clazz) {
        return isBasicComponentType(clazz, true);
    }

    public static boolean isBasicComponentType(Class<?> clazz, boolean valid) {
        return (valid || !isSingleType(clazz)) && isBasicType(clazz.getComponentType());
    }

    public static boolean isNumericType(Class<?> clazz) {
        if (clazz == Integer.class || clazz == int.class
                || clazz == Long.class || clazz == long.class
                || clazz == Double.class || clazz == double.class
                || clazz == Float.class || clazz == float.class
                || clazz == Byte.class || clazz == byte.class
                || clazz == Short.class || clazz == short.class) {
            return true;
        }
        if (clazz == Integer[].class || clazz == int[].class
                || clazz == Long[].class || clazz == long[].class
                || clazz == Double[].class || clazz == double[].class
                || clazz == Float[].class || clazz == float[].class
                || clazz == Byte[].class || clazz == byte[].class
                || clazz == Short[].class || clazz == short[].class) {
            return true;
        }
        return false;
    }

    /**
     * 判断是否是单一类型
     *
     * @param clazz
     * @return
     */
    public static boolean isSingleType(Class<?> clazz) {
        return !ClassUtils.isAssignable(clazz, Collection.class)
                && !ClassUtils.isAssignable(clazz, Map.class)
                && !clazz.isArray();
    }

    /**
     * 判断给定类是否只包含基本类型
     *
     * @param clazz 待检查的类
     * @return 如果包含内嵌引用类型字段，则返回true；否则返回false
     */
    public static boolean isOnlyContainBasicType(Class<?> clazz) {
        for (Field field : clazz.getDeclaredFields()) {
            Class<?> type = field.getType();
            if (type != String.class && !type.isPrimitive()) {
                return false;
            }
        }
        return true;
    }

    /**
     * 判断给定对象是否包含null值
     *
     * @param objs 待检查的对象
     * @return 如果包含null值，则返回true；否则返回false
     */
    public static boolean isAnyNull(Object... objs) {
        for (Object obj : objs) {
            if (obj == null) {
                return true;
            }
        }
        return false;
    }

    public static <T> T copy(T object) {
        T instance = ClassUtil.getInstance((Class<T>) object.getClass());
        try {
            BeanUtils.copyProperties(instance, object);
        } catch (IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }
        return instance;
    }
}
